package com.example.lightble;


import com.sevencar.activity.DeviceFragment;

import android.app.Activity;




import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
public class BLEDeviceManager {


	private BluetoothDevice mDevice;
	private CmdSend mCmdSend;

	private String mSendPasswd=null;  //要发送的密码.
	private int  mConnectStatus;	
	public final static int  CONNSTATUS_NONE=0; //无连接 ,或已断开
	public final static int  CONNSTATUS_ING=1;  //正在连接.
	public final static int  CONNSTATUS_BLE_OK=2;  //系统层面上连接好了.
	public final static int  CONNSTATUS_DEV_OK=3;  //设备连接好.

	
	private final static int CONNECT_COUNT_MAX=5;
	private int connectCount=0;  //连接次数.
	 
	
	private BlueToothService mService;
	private SendPasswdTimeoutAsyncTask mSendPasswdTimeoutAsyncTask;
	private CheckIsExistAsyncTask checkIsExistAsyncTask;
	
	private onStatusChangedListener  mOnStatusChangedListener;
	public interface onStatusChangedListener {
		void onStatusChanged(BLEDeviceManager devmng,int status);    //状态 -1:一致连不上, -2:设备断开后扫描不到.
	}
	public void setOnStatusChangedListener(onStatusChangedListener callback) {
		mOnStatusChangedListener = callback;
	}
	
	private boolean isDisconnectedByUser;
	
	public BLEDeviceManager(BlueToothService service,BluetoothDevice device)
	{
		mService=service;
		mCmdSend=CmdSend.getInstance();
	    mConnectStatus=CONNSTATUS_NONE;
	    mDevice=device;
	    connectCount=0; 
	}
//---------------------------------------------------------------------------------------------------------------
	    /**
	     * 安卓系统层连接上了.
	     */
	    public void setBLEConnected()
	    {
	    	mConnectStatus=CONNSTATUS_BLE_OK;
	    }
	    public BluetoothDevice getDevice()
	    {
	    	return mDevice;
	    }
	    public void connectTimeOut()
	    {
	    	Log.i("sno",mDevice.getAddress()+" 设备连接超时...android....");
	    	reConnectDevice();
	    }
	    public void startConnectByUser()
	    {
	    	 if(mConnectStatus==CONNSTATUS_NONE)
	    	 {
	    		 startConnect();
	    	 }
	    }
	    /**
	     * 扫描到, 则自动重连.
	     */
	    private int devOkButScanedCount; //
	    public  void startConnectAuto()
	    {
	    	 if(mConnectStatus==CONNSTATUS_NONE && isDisconnectedByUser==false && reConnectedFailed==false)  //如用户断开,则不再连接.
	    	 {
	    		 startConnect();
	    	 }
//	    	 else if(mConnectStatus==CONNSTATUS_DEV_OK)  //已经通信可以, 还可以扫描到,则断开重连.这样的方式方式是不行的,因为gatt内部还没有断开,不清楚为什么发断开命令底层也不行.???
//	    	 { 
//	    		 if(devOkButScanedCount++>5){  //造成不同的手机之间死机. 暂时不用.
//	    			 reConnectDevice();
//	    		 }
//	    	 }
	    }
	    private void startConnect()
	    {
			connectCount=CONNECT_COUNT_MAX;
			reConnectedFailed=false;
			mConnectStatus=CONNSTATUS_ING;
    		sendStatusConnecting();
		 	mService.connectBle(mDevice.getAddress());
	    }
	    public void setBLEConnecting(int status,int newState)
	    {
	    	if(newState==BluetoothProfile.STATE_CONNECTED)
	    	{
	    		sendStatusConnecting();
	    	}else if (newState == BluetoothProfile.STATE_DISCONNECTED)   //设备已断开,断开的Operation执行完.
	        {  
	            	if(status==133)  //找服务的时候, 出现129的错误信息或底层出现在连接gatt时有错误,重新连接.
	            	{
	            		reConnectDevice();
	            	}
	            	else
	            	{
	            		if(connectCount==0)
	            		{ 
	            			Log.i("sno","连接状态00 设置断开---");
            				setDisconnect(false,true); 
	            		}
	            	}
	        }
	    }
	    private boolean reConnectedFailed=false;  //连接了10次也不行,重连失败.
	    public void reConnectDevice()   
	    {
	    	if(connectCount>0)
	    	{
	    		sendStatusConnecting();
	    		setDisconnect(false,false);
	    		new ReConnectDelayAsyncTask().execute();
	    	}else{
	    		Log.i("sno",BLEDeviceManager.class.getSimpleName()+":: " +mDevice.getName()+" 连接错误. ..");
	    		setDisconnect(false,true); //实在是连接不上, 删除后重连也不能完全解决问题,最好让客户来处理,而不是一直在后台连接.
	    		if(mOnStatusChangedListener!=null)  //还是重连吧....
	    			mOnStatusChangedListener.onStatusChanged(BLEDeviceManager.this,-1);
	    	}
	    }
	    private void sendReconnectFailded()
	    {
	    	Intent intent = new Intent(DeviceFragment.ACTION_BLEGATT_RECONNECT_FAILED);
	        intent.putExtra("BluetoothDevice",mDevice);
	        mService.sendBroadcast(intent);
	        cancelCheckIsExist();
	    }
	    private void sendStatusConnecting()
	    {
	    	if(mConnectStatus!=CONNSTATUS_NONE)
	    	{
			 	Intent intent = new Intent(DeviceFragment.ACTION_BLEGATT_CONNECTING);
		        intent.putExtra("BluetoothDevice",mDevice);
		        mService.sendBroadcast(intent);
		        cancelCheckIsExist();
	    	}
	    }
	    /**
	     * 自动断开的设备, 则销毁这个,重新创建一个.
	     * @param byUser
	     */
	    public void setDisconnect(boolean byUser,boolean isDefault)
	    {
	    	if(mConnectStatus!=CONNSTATUS_NONE)
	    	{
	    			isDisconnectedByUser=byUser;
					mService.removeFromConnectGattArray(mDevice);
		    		mService.disconnectBle(mDevice); 
		    		
		    		if(isDefault)
		    		{
	    				connectCount=0;
	    				mConnectStatus=CONNSTATUS_NONE;
	    				checkDeviceIsExist();
		    		}
		    		if(byUser==false && connectCount==0)
					{
		    			Log.i("sno",BLEDeviceManager.class.getSimpleName()+ "::setDisconnect设置为断开开开开开开开开开开开开开开开开开. .."+mDevice.getName());	
						Intent intent = new Intent(DeviceFragment.ACTION_BLEGATT_DISCONNECTED);
				        intent.putExtra("BluetoothDevice",mDevice);
				        mService.sendBroadcast(intent);	
					}
		    		
	    	}
	    }
	    private void setConnected(boolean isOpen)
	    {
	    	mConnectStatus=CONNSTATUS_DEV_OK;
	    	mService.addToConnectGattArray(mDevice,isOpen);
			connectCount=0;
			devOkButScanedCount=0;
			
			Intent intent = new Intent(DeviceFragment.ACTION_BLEGATT_CONNECTED);
	        intent.putExtra("BluetoothDevice",mDevice);
	        intent.putExtra("ISOPEN", isOpen);
	        mService.sendBroadcast(intent);
	    }
	    public void sendOpenLightArray(boolean isChecked)
	    {
	    	byte[] test=mCmdSend.getOpenLightArray(isChecked);
	    	mService.sendDataToAddress(test,mDevice.getAddress());
	    }
	    public void sendPasswdTimeOut()
	    {
		    	if(mConnectStatus==CONNSTATUS_BLE_OK)
				{  
						if( connectCount>0){
							connectCount--;
							Log.i("sno","发送密码超时, 再次发送:"+connectCount);
							sendPasswdPkg(mSendPasswd);		
						}else{
							connectCount=0;
							setDisconnect(false,true);
						}
				}
	    }
	    public void sendPasswdPkg()
	    {
	    	if(mSendPasswd==null){
	    		mSendPasswd=mService.getPasswdFromDatabase(mDevice.getAddress());	
	    	}
	    	if(mSendPasswd!=null){
	    		connectCount=CONNECT_COUNT_MAX;
	    		sendPasswdPkg(mSendPasswd);	
	    	}else{
	    		Intent intent = new Intent(DeviceFragment.ACTION_BLEGATT_NEED_NEW_PASSWORD);
		        intent.putExtra("BluetoothDevice",mDevice);
		        mService.sendBroadcast(intent);
	    	}
	    }
        boolean isNewPasswd=false;  
	    public void sendNewPasswdPkg(String passwd)
	    {
	    	isNewPasswd=true;
	    	sendPasswdPkg(passwd);
	    }
	    public void sendPasswdPkg(String passwd)
	    {
		  	mSendPasswd=passwd;
			Log.i("sno","sendBond Pkg:"+mDevice.getName());
	    	byte[] test=mCmdSend.getBondPassWdArray(passwd);
	    	mService.sendDataToAddress(test,mDevice.getAddress());	
	    	
			startPasswdTimeoutThread();
	    }
	    public void parseRcvData(byte[] data)
		  {
				//流程是: 先判断长度,--->校验和---->解密.
	    		cancelPasswdTimeoutThread();
				if(data.length>8)
				{
					if(mCmdSend.checkRcvData(data))  //校验成功.
			    	{
						 int index=(int)(data[5]&0xff);
						if(index>0)  //接收的数据包加密了.
						{
							mCmdSend.DecryptCode(data);
					    	printRcvData("DecryptCode is:",data);
						}
						if(data[4]==0x01)  //返回的是设备状态信息.
						{
							if(mConnectStatus==CONNSTATUS_BLE_OK)
							{
								//开始解析.....
								/*
								 * 返馈内容（返馈命令字用0x01表示）：反馈数据长度11字节，（格式：AA BB CC DD RA GA BA RB GB BB OO），
								 * AA BB为自由跳变颜色状态（值与F命令字对应）； data[7--8]
								 * CC DD为自由渐变颜色状态（值与S命令字对应）；data[9--10]
								 * RA GA BA为写入A组的PWM值（值与A令字对应），data[11-12-13]
								 * RB GB BB为写入B组的PWM值（值与B令字对应）; data[14-15-16]
								 * OO为开关灯状态data[17]
								 */
								if(data[17]>0){
									setConnected(true);
								 }else{
									 setConnected(false);
								 }
								if(isNewPasswd){
									mService.saveBondPasswdToDatabase(mDevice.getAddress(), mSendPasswd);
									isNewPasswd=false;
								}
							}
						}
						else if(data[4]==CmdConstants.CMD_WORD_RET_E)
						{
				    		Log.i("sno","接收数据错误, 错误码是:"+data[7]);
				    		if(data[7]==0x05){  //绑定的密码错误.
				    			 Intent intent = new Intent(DeviceFragment.ACTION_BLEGATT_PASSWD_ERROR);
				 		        intent.putExtra("BluetoothDevice",mDevice);
				 		        mService.sendBroadcast(intent);
				    		}
				    	}
						else if(data[4]==CmdConstants.CMD_WORD_RET_U)
				    	{
				    		Log.i("sno","接收数据错误, 未定义的协议类型");
				    	}
						else if(data[4]==CmdConstants.CMD_WORD_RET_G)
				    	{
				    		String cmd=String.format("%c",data[7]);
				    		mService.showToast();
				    		Log.i("sno","接收数据成功,命令是"+cmd);
				    	}else{
				    		Log.i("sno","LightDevItem:  接收数据错误");
				    	}
			    	}else{
			    		Log.i("sno","LightDevItem:  错误! 解析数据包错误");
			    	}
				}else{  
					Log.i("sno","接收数据包不完整.");
				}
		}
	    private void printRcvData(String hint,byte[] data)
		{
			String printStr=mDevice.getAddress();
			printStr+=" >>> ";
	    	printStr+=Integer.toString(data.length);
	    	printStr+="hex:";
	    	
			for(int i=0;i<data.length;i++)
			{
				 int v = data[i] & 0xFF;
				 printStr+= Integer.toHexString(v);
				 printStr+=" ";
			}
			Log.i("sno",hint+printStr);
		}
		
		
	    public void onDestoryDev(){
	    	setDisconnect(false, true);
		    cancelPasswdTimeoutThread();
	    }
	    private void startPasswdTimeoutThread()
	    {
	    	if(mSendPasswdTimeoutAsyncTask!=null)
	    	{
	    		mSendPasswdTimeoutAsyncTask.cancelWait();
	    	}
	    	mSendPasswdTimeoutAsyncTask=new SendPasswdTimeoutAsyncTask();
	    	mSendPasswdTimeoutAsyncTask.execute();
	    }
	    
	    private void cancelPasswdTimeoutThread()
	    {
	    	if(mSendPasswdTimeoutAsyncTask!=null)
	    	{
	    		mSendPasswdTimeoutAsyncTask.cancelWait();
	    	}
	    	mSendPasswdTimeoutAsyncTask=null;
	    }
	    
	    public class SendPasswdTimeoutAsyncTask extends AsyncTask<Object, Object, Boolean>{
	    	  Object obj= new Object();
	      	   boolean isInterupted=false;
	      	   private int timeCount;
	      	    public synchronized void cancelWait()
	      	    {
	      	    		isInterupted=true;
	      	    }
	      	    @Override
	      	    protected synchronized Boolean doInBackground(Object... params) {
	      	    	// TODO Auto-generated method stub
	      	    	isInterupted=false;
	      	    	timeCount=0;
	      	    	 while(isInterupted==false){
	      	    		 
	      	    		 try {
							wait(100);
							timeCount++;
							if(timeCount>30) //3000ms
							{
								break;
							}
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
	      	    	 }
	      	    	return null;
	      	    }
	    	@Override
	    	protected void onPostExecute(Boolean result) {  //主线程执行的.
	    		// TODO Auto-generated method stub
	    		if(isInterupted){
	    		
	    		}else{
	    			sendPasswdTimeOut();
	    		}
	    		super.onPostExecute(result);
	    	}
	    }
	    public class ReConnectDelayAsyncTask extends AsyncTask<Object, Object, Boolean>{
      	    @Override
      	    protected synchronized Boolean doInBackground(Object... params) {
      	    	// TODO Auto-generated method stub
      	    		 try {
						wait(400);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
      	    	return null;
      	    }
    	@Override
    	protected void onPostExecute(Boolean result) {  //主线程执行的.
    		// TODO Auto-generated method stub
    		super.onPostExecute(result);
    		
    		connectCount--;
    		Log.i("sno",BLEDeviceManager.class.getSimpleName()+" 连接错误. 重新连接...剩下["+connectCount+"]次");
        	mService.connectBle(mDevice.getAddress());
    	}
    }
	    private  void checkIsExistThreadTimeOut()
	    {
//	    	if(checkIsExistAsyncTask!=null && isInterupted==false)
//	    	{
//	    		Log.i("sno",BLEDeviceManager.class.getSimpleName()+" checkIsExisttttttttttttttttttttttttttttt "+ mDevice.getName());
//		    	Intent intent = new Intent(DeviceFragment.ACTION_BLEDEV_NOT_EXIST);
//		        intent.putExtra("BluetoothDevice",mDevice);
//		        mService.sendBroadcast(intent);
//		        
//		    	if(mOnStatusChangedListener!=null)
//	    			mOnStatusChangedListener.onStatusChanged(BLEDeviceManager.this,-2);
//	    	}
//	    	checkIsExistAsyncTask=null;
	    }
	    private void checkDeviceIsExist()
	    {
//	    	if(checkIsExistAsyncTask!=null)
//	    	{
//	    		cancelWait();
//	    	}
//	    	checkIsExistAsyncTask=new CheckIsExistAsyncTask();
//	    	checkIsExistAsyncTask.execute();
//	    	Log.i("sno",BLEDeviceManager.class.getSimpleName()+" checkIsExistCSSSSSSSSSSSSSSSSSSSSSSSSSSSS "+ mDevice.getName());
	    }
	    private void cancelCheckIsExist()
	    {
//	    	Log.i("sno",BLEDeviceManager.class.getSimpleName()+" checkIsExistCCCHECKEEEEEEEEEEEEEE "+ mDevice.getName());
//	    		cancelWait();
//	    	checkIsExistAsyncTask=null;
	    }
	    
	    boolean isInterupted=false;
	    public synchronized void cancelWait()
  	    {
//	    		Log.i("sno",BLEDeviceManager.class.getSimpleName()+" checkIsExistCCCHECKEEEE2222EEEEEEEEEE "+ mDevice.getName());
//  	    		isInterupted=true;
  	    }
		public class CheckIsExistAsyncTask extends AsyncTask<Object, Object, Boolean>{
	    	  Object obj= new Object();
	      	
	      	   private int timeCount;
	      	    @Override
	      	    protected synchronized Boolean doInBackground(Object... params) {
	      	    	// TODO Auto-generated method stub
	      	    	isInterupted=false;
	      	    	timeCount=0;
	      	    	 while(isInterupted==false){
	      	    		 
	      	    		 try {
							wait(100);
							timeCount++;
							if(timeCount>50) //5000ms
							{
								break;
							}
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
	      	    	 }
	      	    	return null;
	      	    }
	    	@Override
	    	protected void onPostExecute(Boolean result) {  //主线程执行的.
	    		// TODO Auto-generated method stub
	    		if(isInterupted){
	    		
	    		}else{
	    			 checkIsExistThreadTimeOut();
	    		}
	    		super.onPostExecute(result);
	    	}
	    }	
	   
}
